const puppeteer  = require('puppeteer');
const path       = require('path');
const utils      = require('./utils');
const logger     = require('./log');

/**
 * 获取一个无头浏览器对象
 */
class browser_factory{
    constructor(options = {}) {
        this.page = null;
        this.browser = null;
        this.cookie = options.cookie;
        this.openInterception = options.openInterception;
    }

    /**
     * 获取一个浏览器实例
     */
    async getInstall(){
        await this.initPageModule();
        await this.loadInterception();
        await this.camouflageBrowser();
        return this;
    }

    /**
     * 访问指定页面
     */
    async gotoUrl(url){
        await this.addCookies(url);
        //默认页面的加载方式 domcontentloaded
        await this.page.goto(url,{waitUntil: 'domcontentloaded'});
        //默认注入jquery
        await this.page.addScriptTag({
            path: path.resolve(__dirname,'../../lib/jquery.js'),
        });
    }

    /**
     * 获取当前tab页面
     */
    async getPage(){
        return this.page;
    }

    /**
     * 构建浏览器内核
     */
    async initPageModule(options = {hide:false}){
        //构建内核对象
        this.browser = await puppeteer.launch({
            headless: options.hide ? options.hide : false,
            ignoreHTTPSErrors: false,
            credentialsEnableService:false,
            ignoreDefaultArgs: ['--enable-automation']
        });
        this.page = await this.browser.newPage();
        await this.page.setViewport({width:1920, height:1080});
        await this.page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36');
    }

    /**
     * 注入初始cookie
     */
    async addCookies(url){
        if(!this.cookie || '' === this.cookie){
            return;
        }
        let domain = utils.parserUrlDomain(url);
        let cookies = this.cookie.split(';').map(
            pair => {
                let name = pair.trim().slice(0, pair.trim().indexOf('='));
                let value = pair.trim().slice(pair.trim().indexOf('=') + 1);
                return {name, value, domain}
            });
        await Promise.all(cookies.map(pair => {
            return this.page.setCookie(pair)
        }));
        logger.info(`Inject cookie. Domain: <${domain}>`);
    }

    async camouflageBrowser(){
        //删掉webdriver属性 以免被检测出为无头浏览器
        await this.page.evaluateOnNewDocument(() => {
            const newProto = navigator.__proto__;
            delete newProto.webdriver;
            navigator.__proto__ = newProto;
        });

        //无头浏览器模式下,全局对象下的chrome对象是没有 runtime属性的
        await this.page.evaluateOnNewDocument(() => {
            window.navigator.chrome = {
                runtime: {}
            };
        });

    }


    /**
     * 关闭浏览器
     */
    async closeWindows(){
        let pages = await this.browser.pages();
        await pages.forEach(item => item.close());
        await this.browser.close();
    }

    /**
     * 加载拦截器
     */
    async loadInterception() {
        if(!this.openInterception){
            logger.info(`Close Interception...`);
            return;
        }
        logger.info(`Active Interception...`);
        //开启拦截器
        await this.page.setRequestInterception(true);
        //设置不加载图片
        this.page.on('request',async (request) => {
            // 如果文件类型为image,则中断加载
            if (request.resourceType() === 'image') {
                request.abort();
                return;
            }
            // 正常加载其他类型的文件
            request.continue();
        });
    }
}
module.exports = browser_factory;
